import fs, { mkdirSync, writeFileSync } from 'fs';
import path, { dirname, join } from 'path';
import { fileURLToPath } from 'url';
import readline from 'readline';
import 'jsonlines';
import { oImages2, Puppeteer, plugin, getCurrentTime, convertToGanZhi } from 'mz-botjs';
import { Redis } from 'ioredis';
import 'axios';
import React from 'react';
import { renderToString } from 'react-dom/server';
import schedule from 'node-schedule';

// 获取前文件的 URL
const __filename = fileURLToPath(import.meta.url);
// 获取当前文件所在的目录
const Dirpath = dirname(__filename);
const AppName = path.basename(Dirpath);

const data = path.join(Dirpath, 'public', 'data');
const defaultConfigPath = path.join(data, 'default_config');
const player_path = path.join(data, 'user');
const uid_path = path.join(data, 'uid', 'uid.json');
const default_player = path.join(defaultConfigPath, 'player.json');
const default_equipment = path.join(defaultConfigPath, 'equipment.json');
const default_bag = path.join(defaultConfigPath, 'bag.json');
const item = path.join(data, 'item');
const default_status = path.join(defaultConfigPath, 'status.json');
const help = path.join(data, 'help', 'help.json');
const directives_path = path.join(data, 'directives', 'directives.json');

const url = {
  0: "",
  1: data, //data路径
  2: uid_path,
  3: player_path,
  4: default_player,
  5: default_equipment,
  6: default_bag,
  7: item,
  8: default_status,
  9: help,
  10: directives_path,
};

/**
 *
 * @param {*} num 路径数字
 * @param  {...any} path
 */
async function read_json(num, ...paths) {
  try {
    const Path = path.join(url[num], ...paths);
    const fileStream = fs.createReadStream(Path, "utf8");
    const rl = readline.createInterface({
      input: fileStream,
      crlfDelay: Infinity,
    });

    const lines = [];
    for await (const line of rl) {
      lines.push(line);
    }

    const json = JSON.parse(lines.join(""));
    return json;
  } catch (err) {
    console.log(err);
    return "error";
  }
}

async function write_json(num, json, ...paths) {
  try {
    const Path = path.join(url[num], ...paths);
    const new_ARR = JSON.stringify(json, "", "\t");
    await fs.writeFileSync(Path, new_ARR, "utf8");
  } catch (err) {
    console.log(err);
  }
}
async function exist_player(num, id) {
  if (num == 1) return await find_uid(id);
}

async function read_player(num, id, Options = {}) {
  let result = {};
  if (num == 1) {
    let {
      player = false,
      bag = false,
      equipment = false,
      status = false,
    } = Options;
    if (!player && !bag && !equipment && !status) {
      player = true;
      bag = true;
      equipment = true;
      status = true;
    }
    let uid = await find_uid(id);
    uid = !uid ? (uid = player.uid) : (uid = uid.uid);
    const playerpath = path.resolve(url[3], uid.toString());
    if (player)
      result.player = await read_json(0, path.join(playerpath, "player.json"));
    if (bag) result.bag = await read_json(0, path.join(playerpath, "bag.json"));
    if (equipment)
      result.equipment = await read_json(
        0,
        path.join(playerpath, "equipment.json")
      );
    if (status)
      result.status = await read_json(0, path.join(playerpath, "status.json"));
  }
  return result;
}
async function write_player(id, Options = {}) {
  const { player, bag, equipment, status } = Options;
  let uid = await find_uid(id);
  uid = !uid ? (uid = player.uid) : (uid = uid.uid);
  const playerpath = path.resolve(url[3], uid.toString());
  try {
    await fs.promises.access(playerpath);
  } catch (error) {
    await fs.promises.mkdir(playerpath, { recursive: true });
  }
  const writePromises = [];
  if (player) {
    writePromises.push(
      write_json(0, player, path.resolve(playerpath, "player.json"))
    );
  }
  if (bag) {
    writePromises.push(
      write_json(0, bag, path.resolve(playerpath, "bag.json"))
    );
  }
  if (equipment) {
    writePromises.push(
      write_json(0, equipment, path.resolve(playerpath, "equipment.json"))
    );
  }
  if (status) {
    writePromises.push(
      write_json(0, status, path.resolve(playerpath, "status.json"))
    );
  }
  await Promise.all(writePromises);
}

async function find_uid(user_id) {
  let id = await read_json(2);
  const x = id.find((item) => item.绑定账号 == user_id);
  if (x) return x;
  const xx = id.find((item) => item.uid == user_id);
  return xx;
}
/**
 * 根据权重进行随机抽取
 * @param {*} arr 数组
 * @returns
 */
async function rouletteWheelSelection(arr) {
  // 计算总权重
  const totalWeight = arr.reduce((sum, item) => sum + item.权重, 0);

  // 生成一个随机数，范围在0到总权重之间
  const randomNum = Math.random() * totalWeight;

  let accumulatedWeight = 0;

  // 遍历数组，累加权重，并找到第一个累加权重大于随机数的元素
  for (const item of arr) {
    accumulatedWeight += item.权重;
    if (accumulatedWeight >= randomNum) {
      return item;
    }
  }

  // 如果没有找到符合条件的元素，则返回 null
  return null;
}
async function Strand(now, max) {
  let num;
  if (now <= 0) {
    num = Math.floor((now || 0 / max) * 100);
  } else if (now >= max) {
    num = 100;
  } else {
    num = Math.floor(Math.abs((now || 0 / max) * 100));
  }
  const numWithSign = now < 0 ? -num : num;
  const style = `style=width:${num}%`;
  return {
    style,
    num: numWithSign,
  };
}
/**
 * 寻找物品数组
 * @param thing_name 物品名
 */
async function find_thing(thing_name) {
  let list = ["道具列表", "功法列表", "装备列表"];
  let promises = list.map(async (element) => {
    let things = await read_json(7, `${element}.json`);
    return things.find((item) => item.name === thing_name);
  });
  let results = await Promise.all(promises);
  return results.find((thing) => thing !== undefined);
}
/**
 * 创建战斗存档
 * @param player 存档
 * @returns
 */
async function createPlayerObject(player) {
  return {
    name: player?.名号 || player.name,
    灵气: player?.练气境.灵气 || player.灵气 || 0,
    暴击加成: player.暴击加成 || 0,
    爆伤加成: player.爆伤加成 || 0,
    攻击加成: player.攻击加成 || 0,
    闪避加成: player.闪避加成 || 0,
    防御加成: player.防御加成 || 0,
    体质: player.体质 || null,
    当前生命: player.当前血量 || player.生命加成,
    技能栏: player.技能栏 || {
      技能1: null,
      技能2: null,
      技能3: null,
      技能4: null,
      技能5: null,
      技能6: null,
      技能7: null,
      技能8: null,
    },
    武器熟练度: player.武器熟练度 || null,
    equipment: player.equipment || null,
  };
}

/**
 * 进行伤害计算
 */
async function calculateDamage(player) {
  let 伤害 = player.攻击加成;
  if (player.equipment && player.equipment.武器) {
    if (player.武器熟练度[player.equipment.武器.类型 + "等级"]) {
      伤害 *=
        weaponSkillLevel[
          player.武器熟练度[player.equipment.武器.类型 + "等级"]
        ];
    }
  }
  return 伤害;
}

async function getskill(skill, A_buff, B_buff, msg) {
  const skillEffects = {
    天地一刀斩: { buff: "眩晕", duration: 2, message: "对对方产生了眩晕效果" },
    "小朱雀指(假)": {
      buff: "小朱雀指(假)灼烧",
      duration: 2,
      message: "对对方产生了灼烧效果,持续两回合",
    },
    紫府手: {
      buff: "紫府手淬毒",
      duration: 3,
      message: "对对方产生了淬毒效果,持续三回合",
    },
  };

  if (skill.name in skillEffects) {
    const { buff, duration, message } = skillEffects[skill.name];
    msg.push(message);
    const existingBuff = B_buff.find((item) => item.buff === buff);
    if (existingBuff) {
      existingBuff.持续回合数 += 1;
    } else {
      B_buff.push({ buff, 持续回合数: duration, 当前回合数: 1 });
    }
  }

  return { A_buff, B_buff, msg };
}

/**
 * 进行功法暴击计算
 * @param {*} skill
 * @param {*} player
 * @returns
 */
async function isskillCriticalHit(skill, player) {
  const random = Math.random();
  const isCritical = random < player.暴击加成 + skill.暴击加成;
  const criticalDamageMultiplier = 1 + player.爆伤加成 + skill.爆伤加成;
  return isCritical
    ? skill.攻击加成 * criticalDamageMultiplier
    : skill.攻击加成 || 0;
}

async function skill_load(player, msg, skill_name) {
  const thing = (await find_thing(skill_name)) || null;
  let damage = 0;
  if (!thing) return { msg, damage };
  if (thing.name == "小朱雀指(假)") {
    msg.push(`【${player.name}】使出了${thing.name}造成了150的灼烧伤害`);
    damage += 150;
  } else if (thing.name == "紫府手") {
    msg.push(`【${player.name}】使出了${thing.name}造成了125的淬毒伤害`);
    damage += 125;
  }
  return { msg, damage };
}

/**
 * 进行功法触发的处理
 * @param {*} A_player
 * @param {*} currentSkill
 * @param {*} buff
 * @param {*} msg
 * @returns
 */
async function handleSkill(A_player, currentSkill, buff, msg, 冷却) {
  let skill = await find_thing(A_player.技能栏[`技能${currentSkill}`]);
  if (!冷却) 冷却 = [];
  console.log(currentSkill);
  for (let i = currentSkill; i <= 8; i++) {
    const currentSkillName = A_player.技能栏[`技能${i}`];
    if (!currentSkillName) continue; // 如果当前技能栏为空，则跳过
    if (!冷却.find((item) => item.name === currentSkillName)) {
      skill = await find_thing(currentSkillName);
      break; // 找到技能后跳出循环
    }
  }
  if (skill && !skill.冷却) skill.冷却 = 0;
  let damage = 0;
  if (skill && A_player.灵气 >= skill.灵气) {
    const {
      A_buff,
      B_buff,
      msg: msg2,
    } = await getskill(skill, buff.A_buff, buff.B_buff, msg);
    currentSkill += 1;
    damage = await isskillCriticalHit(skill, A_player);
    msg2.push(`【${A_player.name}】使出了${skill.name}造成了${damage}的伤害`);
    const skill冷却 = 冷却.find((item) => item.name == skill.name);
    if (skill冷却) {
      skill冷却.冷却回合数 += skill.冷却;
    } else {
      冷却.push({
        name: skill.name,
        冷却回合数: skill.冷却,
        当前冷却回合: 0,
      });
    }
    let { msg: msg3, damage: damage1 } = await skill_load(
      A_player,
      msg2,
      skill.name
    );
    damage += damage1;

    return { msg3, A_buff, B_buff, damage };
  }

  return {
    msg,
    A_buff: buff.A_buff,
    B_buff: buff.B_buff,
    damage,
    冷却,
    currentSkill,
  };
}

/**
 *进行暴击判断
 */
async function isCriticalHit(player) {
  const random = Math.random();
  const damage = await calculateDamage(player);
  const isCritical = random < player.暴击加成;
  const criticalDamageMultiplier = 1 + player.爆伤加成;
  return isCritical ? damage * criticalDamageMultiplier : damage || 0;
}

const buffToSkillName = {
  " 小朱雀指(假)灼烧": "小朱雀指(假)",
  紫府手淬毒: "紫府手",
};
/**
 *进行玩家战斗
 * @param A_player 玩家存档
 * @param B_player 玩家存档
 */
async function playerBattle(A_player, B_player) {
  let 当前技能 = 1;
  let 当前技能2 = 1;
  let A_冷却 = [];
  let B_冷却 = [];
  let A_buff = [];
  let B_buff = [];
  let winner;
  let msg = [];
  const assignBuffNames = () => {
    A_buff.forEach((buff) => (buff.name = "A"));
    B_buff.forEach((buff) => (buff.name = "B"));
  };
  const updateBuffStatus = (buff) => {
    if (buff.length > 0) {
      buff = buff.filter(async (element) => {
        const player = element.name === "A" ? A_player : B_player;
        console.log(element.buff);
        const skillload = await skill_load(
          player,
          msg,
          buffToSkillName[element.buff]
        );
        msg = skillload.msg;

        player.当前生命 -= skillload?.damage || 0;

        element.当前回合数 += 1;
        return element.当前回合数 <= element.持续回合数;
      });
    }
  };
  const updateSkillStatus = (冷却) => {
    if (冷却.length > 0) {
      冷却 = 冷却.filter(async (element) => {
        element.当前冷却回合 += 1;
        return element.当前冷却回合 <= element.冷却回合数;
      });
    }
  };
  while (A_player.当前生命 > 50 && B_player.当前生命 > 50) {
    assignBuffNames();
    [(B_buff)].forEach(updateBuffStatus);
    [(B_冷却)].forEach(updateSkillStatus);
    let A_眩晕 = A_buff.find((item) => item.buff === "眩晕");
    let B_眩晕 = B_buff.find((item) => item.buff === "眩晕");

    当前技能 = 当前技能 == 8 ? 1 : 当前技能;
    当前技能2 = 当前技能2 == 8 ? 1 : 当前技能2;

    if (!A_眩晕) {
      const skillDamage = await handleSkill(
        A_player,
        当前技能,
        { A_buff, B_buff },
        msg,
        A_冷却
      );
      msg = skillDamage.msg3 || skillDamage.msg;
      B_player.当前生命 -= skillDamage.damage;
      A_buff = skillDamage.A_buff;
      B_buff = skillDamage.B_buff;
      A_冷却 = skillDamage.冷却;
      当前技能++;
    }
    if (B_player.当前生命 < 50) {
      msg.push(`【${B_player.name}】战败了`);
      winner = A_player.name;
      break;
    }
    A_眩晕 = A_buff.find((item) => item.buff === "眩晕");
    B_眩晕 = B_buff.find((item) => item.buff === "眩晕");
    if (!B_眩晕) {
      const skill2Damage = await handleSkill(
        B_player,
        当前技能2,
        { A_buff, B_buff },
        msg,
        B_冷却
      );
      msg = skill2Damage.msg3 || skill2Damage.msg;
      B_player.当前生命 -= skill2Damage.damage;
      A_buff = skill2Damage.A_buff;
      B_buff = skill2Damage.B_buff;
      B_冷却 = skill2Damage.冷却;
      当前技能2++;
    }
    if (A_player.当前生命 < 50) {
      msg.push(`【${A_player.name}】战败了`);
      winner = B_player.name;
      break;
    }
    if (!A_眩晕) {
      const A_damage = await isCriticalHit(A_player);
      msg.push(
        `【${A_player.name}】对【${B_player.name}】造成了${A_damage}的伤害`
      );
      B_player.当前生命 -= A_damage;
    }

    if (B_player.当前生命 < 50) {
      msg.push(`【${B_player.name}】战败了`);
      winner = A_player.name;
      break;
    }

    if (!B_眩晕) {
      const B_damage = await isCriticalHit(B_player);
      msg.push(
        `【${B_player.name}】对【${A_player.name}】造成了${B_damage}的伤害`
      );
      A_player.当前生命 -= B_damage;
    }

    if (A_player.当前生命 < 50) {
      msg.push(`【${A_player.name}】战败了`);
      winner = B_player.name;
      break;
    }
  }
  return {
    msg,
    winner,
    A_damage: B_player.当前生命,
    B_damage: A_player.当前生命,
  };
}

class RedisManager {
  constructor(prefix, options = {}) {
    this.client = new Redis(options);
    this.prefix = prefix;
    this.client.on("error", (err) => {
      this.emit("error", err);
    });
  }
  /**
   *
   * @param {*} field key的值
   * @returns
   */
  mapFieldToKey(field) {
    return `${this.prefix}${field}`;
  }
  /**
   * 设置redi数据
   * @param {*} key key的建
   * @param {*} data 数据
   * @returns
   */
  async set_redis_key(key, data) {
    const redisKey = this.mapFieldToKey(key);
    return this.client.set(redisKey, JSON.stringify(data));
  }
  /**
   * 得到redi数据
   * @param {*} key key的建
   * @returns
   */
  async get_redis_key(key) {
    const redisKey = this.mapFieldToKey(key);
    const value = await this.client.get(redisKey);
    return value ? JSON.parse(value) : null;
  }
  /**
   * 删除redi数据
   * @param {*} key key的建
   * @returns
   */
  async del_redis_key(key) {
    const redisKey = this.mapFieldToKey(key);
    return this.client.del(redisKey);
  }
  /**
   * 得到包含key的所有值
   * @param {*} partialKey key的建
   * @returns
   */
  async get_all_redis_key(partialKey) {
    const redisKeyPrefix = this.mapFieldToKey(partialKey);
    const result = [];
    let cursor = "0";
    do {
      const [newCursor, matchingKeys] = await this.client.scan(
        cursor,
        "MATCH",
        `*${redisKeyPrefix}*`,
        "COUNT",
        100 // 限制每次迭代返回的键的数量
      );
      cursor = newCursor;
      if (matchingKeys.length > 0) {
        const pipeline = this.client.pipeline();
        matchingKeys.forEach((matchingKey) => {
          pipeline.get(matchingKey);
        });
        const values = await pipeline.exec();
        values.forEach(([_, value]) => {
          if (value) {
            result.push(JSON.parse(value));
          }
        });
      }
    } while (cursor !== "0");
    return result;
  }

  dispose() {
    this.client.disconnect();
  }

  /**
   * 触发事件
   * @param {*}eventName 事件名
   * @returns
   */
  emit(eventName, ...args) {
    process.emit(eventName, ...args);
  }
}

const redisManager = new RedisManager("xiuxian-plugin-", {
  host: "localhost",
  port: 6379,
});

async function read_default_user() {
  const [new_player, new_equipment, new_bag, new_status, fileMsg] =
    await Promise.all([
      read_json(4),
      read_json(5),
      read_json(6),
      read_json(8),
      read_json(2),
    ]);
  // const fileMsg = await read_json(2)
  const fileCount = fileMsg.length === 0 ? 1 : fileMsg.length;
  return {
    new_player,
    new_equipment,
    new_bag,
    fileCount,
    new_status,
  };
}
/**
 * 获取灵根
 * @param {*} e
 * @returns
 */
async function get_Spiritual_Root() {
  const readJsonLinesPromises = [
    read_json(7, "/灵根列表-绝世灵根.json"),
    read_json(7, "/灵根列表-极品.json"),
    read_json(7, "/灵根列表-天级.json"),
    read_json(7, "/灵根列表-地级.json"),
    read_json(7, "/灵根列表-高级.json"),
    read_json(7, "/灵根列表-中级.json"),
    read_json(7, "/灵根列表-低级.json"),
    read_json(7, "/灵根列表-超低级.json"),
    read_json(7, "/灵根列表-废品.json"),
  ];
  const all_Spiritual_Root = (await Promise.all(readJsonLinesPromises)).flat();
  if (!all_Spiritual_Root) return console.log("灵根列表出错");
  let Spiritual_Root = await rouletteWheelSelection(all_Spiritual_Root);
  if (Spiritual_Root === null) {
    Spiritual_Root =
      all_Spiritual_Root[Math.floor(Math.random() * weightArr.length)];
  }
  return Spiritual_Root;
}
/**
 * 随机获取9位数uid
 * @returns
 */
async function generateUID() {
  const num = await getPlayerCount();
  return 100000000 + num;
}
/**
 * 获取玩家存档
 */
async function getPlayerCount() {
  return (await read_json(2)).length;
}
/**
 * 增加物品
 * @param usr_qq 玩家id
 * @param thing_name 物品名
 * @param 数量
 * @param thing 物品的信息
 */
async function add_bag_thing(usr_qq, thing_name, 数量, thing) {
  let { bag } = await read_player(1, usr_qq, { bag: true });

  if (!thing || thing == "无") thing = await find_thing(thing_name);

  if (!bag[thing.type]) bag[thing.type] = [];

  let bag_thing_index = bag[thing.type].findIndex(
    (item) => item.name === thing_name
  );

  if (bag_thing_index !== -1) {
    bag[thing.type][bag_thing_index].数量 += parseInt(数量);
    if (bag[thing.type][bag_thing_index].数量 <= 0) {
      bag[thing.type].splice(bag_thing_index, 1);
    }
  } else {
    bag[thing.type].push({
      ...thing,
      数量: parseInt(数量),
    });
  }

  await write_player(usr_qq, { bag });
}
async function get_tupo(e, 列表名, 玩家境界名) {
  if (!(await exist_player(1, e.user_id))) return;
  let { player } = await read_player(1, e.user_id, { player: true });
  let list = await read_json(7, `/${列表名}.json`);
  let now_level_id = list.findIndex(
    (item) => item.name == player[玩家境界名].name
  );
  if (now_level_id == list.lenght) return e.reply(`以达到境界上限`);
  let now_level = list.find((item) => item.name == player[玩家境界名].name);
  let use_thing = "灵气";
  if (玩家境界名 == "炼体境") use_thing = "血气";
  else if (玩家境界名 == "灵魂境") use_thing = "灵魂力量";
  if (player[use_thing] < now_level[use_thing])
    return e.reply(`灵气不足,还需${now_level[use_thing] - player[use_thing]}`);
  let rand = Math.random();
  let prob = 1 - now_level_id / 60;
  if (rand > prob) {
    const messages = [
      "你突破中突然又想到等会要去买台遥遥领先玩，突破失败",
      "旁边的山突然塌了，你被余波扰乱心智，突破失败",
      "突然有人喊道，有两个女人在大街上打架还撕扯上衣服，你想去看看，突破失败",
      "突然有道雷劈到了你身上，突破失败",
      "你的脑海中突然想起了一道声音:遥遥领先,遥遥领先...你突破失败",
      "突破失败",
    ];

    let replyMessage = "突破失败";
    const bad_rand = Math.random();
    if (bad_rand > 0.7) replyMessage = messages[0];
    else if (bad_rand > 0.5) replyMessage = messages[1];
    else if (bad_rand > 0.4) replyMessage = messages[2];
    else if (bad_rand > 0.6) replyMessage = messages[3];
    else if (bad_rand > 0.3) replyMessage = messages[4];
    e.reply(replyMessage);
  } else {
    let x = list[now_level_id + 1];
    player[玩家境界名] = x;
    const attributes = ["攻击加成", "防御加成", "生命加成"];
    attributes.forEach((attribute) => {
      if (attribute == "生命加成") {
        player["血量上限"] += x["生命加成"];
      } else {
        player[attribute] += x[attribute];
      }
    });
    e.reply(`突破成功，当前境界${x.name}`);
  }
  player[use_thing] -= now_level[use_thing];
  await write_player(e.user_id, { player });
}
async function getNonZeroValues(obj) {
  let nonZeroValues = null;
  for (let key in obj) {
    if (obj[key] !== 0) {
      nonZeroValues = key;
    }
  }
  return nonZeroValues;
}
async function get_status(e, status状态) {
  if (!(await exist_player(1, e.user_id))) return;
  let { player, status } = await read_player(1, e.user_id, {
    player: true,
    status: true,
  });
  if (player.练气境 == "凡境") return e.reply(`未入仙途`);
  const now_status = await getNonZeroValues(status);
  if (now_status) return e.reply(`你在${now_status}`);
  status[status状态] = new Date().getTime();
  e.reply(`【${player.名号}】开始${status状态}`);
  await write_player(e.user_id, { status });
}
async function getCurrentFunctionName(e) {
  if (!(await exist_player(1, e.user_id))) return;
  let { status, player } = await read_player(1, e.user_id, {
    player: true,
    status: true,
  });
  const now_status = await getNonZeroValues(status);
  if (!now_status) return e.reply(`空闲中`);
  let x = status[now_status];
  const minutes = Math.floor((new Date().getTime() - x) / 60000);
  const seconds = (((new Date().getTime() - x) % 60000) / 1000).toFixed(0);
  e.reply(
    `【${player.名号}】正在${now_status}中，已过了${minutes} 分 ${seconds} 秒`
  );
}
async function state_settlement(e) {
  if (!(await exist_player(1, e.user_id))) return;
  let { player, status } = await read_player(1, e.user_id, {
    player: true,
    status: true,
  });
  const now_status = await getNonZeroValues(status);
  if (!now_status) return e.reply(`空闲中`);
  const now = new Date().getTime();
  if (
    now_status == "闭关" ||
    now_status == "锻炼体魄" ||
    now_status == "锤炼灵魂" ||
    now_status == "打工"
  ) {
    const { attribute, ratio } =
      now_status === "闭关"
        ? { attribute: "灵气", ratio: 0.7 }
        : now_status === "锻炼体魄"
        ? { attribute: "血气", ratio: 0.6 }
        : now_status === "锤炼灵魂"
        ? { attribute: "灵魂力量", ratio: 0.6 }
        : { attribute: ".货币.低级灵石", ratio: 0.7 };
    get_status_settlement(e, player, status, now_status, ratio, attribute);
  } else if (now_status == "猎杀妖兽") {
    const time_value = (now - status[now_status]) / 1000 / 60;
    const value1 = Math.floor(time_value * 0.5);
    const value2 = Math.floor(time_value * 0.4);
    const value3 = Math.floor(time_value * 0.3);
    player.血气 += value3;
    player.金钱 += value1;
    player.灵气 += value2;
    e.reply(
      `【${player.名号}】成功结束猎杀妖兽\n获得血气${value3}\n获得金钱${value1}\n获得灵气${value2}`
    );
  } else if (now_status == "练习武器") {
    if (!player.武器熟练度)
      player.武器熟练度 = {
        枪熟练度: 0,
        剑熟练度: 0,
        弓熟练度: 0,
        棍熟练度: 0,
        枪等级: null,
        剑等级: null,
        弓等级: null,
        棍等级: null,
      };
    const wuqi_type = await redisManager.get_redis_key(
      "practise-wuqi" + player.uid
    );
    const time = Math.floor((now - status[now_status]) / 1000 / 60 / 60);
    player.武器熟练度[wuqi_type + "熟练度"] += time;
    e.reply(`【${player.名号}】结束了训练${wuqi_type},获得${time}点熟练度`);
  }
  status[now_status] = 0;
  await write_player(player.uid, { player, status });
}
async function get_status_settlement(
  e,
  player,
  status,
  now_status,
  获取倍率,
  玩家属性
) {
  const now = new Date().getTime();
  const time_value = (now - status[now_status]) / 1000 / 60;
  const value = Math.floor(time_value * 获取倍率 + player.修炼效率);
  player[玩家属性] += value;
  status[now_status] = 0;
  await write_player(player.uid, { player, status });
  e.reply(`【${player.名号}】成功结束${玩家属性}，获得${玩家属性}${value}`);
}
async function modifyPlayerInfo(e) {
  if (!(await exist_player(1, e.user_id))) return;
  let { player } = await read_player(1, e.user_id, { player: true });

  let action;
  e.msg.includes("改名")
    ? (action = "改名")
    : e.msg.includes("修改道宣")
    ? (action = "修改道宣")
    : (action = "改性");
  let [name] = e.msg
    .replace(new RegExp("(\\/|#)" + action + "?"), "")
    .trim()
    .split("*")
    .map((code) => code.trim());
  if (!name) return e.reply(`缺失参数`);
  switch (action) {
    case "改名":
      player.名号 = name;
      e.reply(`【${player.名号}】改名成功`);
      break;
    case "修改道宣":
      player.道宣 = name;
      e.reply(`【${player.名号}】修改道宣成功`);
      break;
    case "改性":
      player.性别 = name;
      e.reply(`【${player.名号}】改性成功`);
      break;
    default:
      return e.reply(`无效的操作`);
  }
  await write_player(e.user_id, { player });
}
/**
 *
 * @param {*} player
 * @param {*} thing
 * @param {*} isIncrease false 减法 true 反之
 * @param {*} type
 */
function updatePlayerAttributes(
  player,
  thing,
  isIncrease, // 新增的布尔参数，控制加减
  type = [
    "攻击加成",
    "防御加成",
    "生命加成",
    "暴击加成",
    "爆伤加成",
    "修炼加成",
  ]
) {
  type.forEach((element) => {
    const operation = isIncrease ? 1 : -1;
    if (element == "生命加成") {
      player.血量上限 += thing[element] * operation;
    } else {
      player[element] += thing[element] * operation;
    }
  });
  return player;
}
function find_equipment(bag, equipment, equiment_calss) {
  let maxValue = 0;
  let equipmentName = null;
  if (equipment) {
    maxValue =
      (equipment.攻击加成 || 0) +
      (equipment.防御加成 || 0) +
      (equipment.生命加成 || 0) +
      (equipment.暴击加成 || 0) +
      (equipment.爆伤加成 || 0) +
      (equipment.修炼加成 || 0);
    equipmentName = equipment.name;
  }
  if (!equipment) equipment = { class: equiment_calss };
  const allEquipment = bag.装备.filter(
    (item) => item.class === equipment.class
  );
  for (const item of allEquipment) {
    const currentValue =
      (item.攻击加成 || 0) +
      (item.防御加成 || 0) +
      (item.生命加成 || 0) +
      (item.暴击加成 || 0) +
      (item.爆伤加成 || 0) +
      (item.修炼加成 || 0);

    if (currentValue > maxValue) {
      maxValue = currentValue;
      equipmentName = item.name;
    }
  }
  return typeof equipmentName === "object" ? null : equipmentName;
}

/**
 * 可以在战斗中使用的技能
 */
/**
 * 道具
 */
const item_value = {
  低级强灵丹: 100,
};
/**
 * 秘境冷却
 */
const mijingCD = 5 * 60 * 1000;
/**
 * 武器类型
 */
const weaponTypes = {
  枪: "枪",
  剑: "剑",
  棍: "棍",
  弓: "弓",
};
/**
 * 武器熟练度
 */
const Weapon_proficiency = {
  初窥门道: 25,
  熟练: 55,
  精通: 100,
  大成: 155,
  完美: 260,
  极致: 500,
};
/**
 * 武器熟练度对应提升伤害
 */
const weaponSkillLevel = {
  初窥门道: 0.01,
  熟练: 0.03,
  精通: 0.05,
  大成: 0.7,
  完美: 0.09,
  极致: 0.1,
};

let directives = {
  start: [
    {
      reg: /^(#|\/)?改名.*$/,
      fnc: "rename",
    },
    {
      reg: /^(#|\/)?踏入凡世$/,
      fnc: "born",
    },
    {
      reg: /^(#|\/)?个人信息$/,
      fnc: "personal_information",
    },
    {
      reg: /^(#|\/)?寻仙缘$/,
      fnc: "Seeking_Immortal_Destiny",
    },
    {
      reg: /^(#|\/)?修仙帮助$/,
      fnc: "help",
    },
    {
      reg: /^(#|\/)?修改道宣.*$/,
      fnc: "Modify_Daoyuan",
    },
    {
      reg: /^(#|\/)?改性.*$/,
      fnc: "Change_surname",
    },
  ],
  status: [
    {
      reg: /^(#|\/)?闭关$/,
      fnc: "biguan",
    },
    {
      reg: /^(#|\/)?锻炼体魄$/,
      fnc: "duanlian",
    },
    {
      reg: /^(#|\/)?锤炼灵魂$/,
      fnc: "chuilian",
    },
    {
      reg: /^(#|\/)?当前状态$/,
      fnc: "now_status",
    },
    {
      reg: /^(#|\/)?状态结算$/,
      fnc: "state_settlement",
    },
    {
      reg: /^(#|\/)?开始打工$/,
      fnc: "dagong",
    },
    {
      reg: /^(#|\/)?开始猎杀妖兽$/,
      fnc: "lieyao",
    },
  ],
  tupo: [
    {
      reg: /^(#|\/)?(修为|体魄|灵魂|血气)突破$/,
      fnc: "tupo",
    },
  ],
  show: [
    {
      reg: /^(#|\/)?我的背包$/,
      fnc: "my_bag",
    },
  ],
  mysterious_realm: [
    {
      reg: /^(#|\/)?查看秘境.*$/,
      fnc: "check_mijing",
    },
    {
      reg: /^(#|\/)?前往秘境.*$/,
      fnc: "go_mijing",
    },
    {
      reg: /^(#|\/)?查看已结算秘境.*$/,
      fnc: "check_stop_mijing",
    },
  ],
  skill: [
    {
      reg: /^(#|\/)?配置技能栏.*$/,
      fnc: "configuration",
    },
    {
      reg: /^(#|\/)?查看技能栏$/,
      fnc: "check_skill",
    },
  ],
  use: [
    {
      reg: /^(#|\/)?使用.*$/,
      fnc: "use",
    },
    {
      reg: /^(#|\/)?出售.*$/,
      fnc: "sell",
    },
  ],
  zhandou: [
    {
      reg: /^(#|\/)?比斗.*$/,
      fnc: "Battlefield",
    },
  ],
  equiment: [
    {
      reg: /^(#|\/)?练习(枪|剑|弓|棍)$/,
      fnc: "practise_",
    },
    {
      reg: /^(#|\/)?突破(枪|剑|弓|棍)熟练度$/,
      fnc: "tupo_",
    },
    {
      reg: /^(#|\/)?查看武器熟练度$/,
      fnc: "check_wuqi",
    },
    {
      reg: /^(#|\/)?装备.*$/,
      fnc: "equipment",
    },
    {
      reg: /^(#|\/)?一键装备$/,
      fnc: "all_equipment",
    },
    {
      reg: /^(#|\/)?卸下装备.*$/,
      fnc: "remove_gear",
    },
    {
      reg: /^(#|\/)?我的装备$/,
      fnc: "myEquipment",
    },
  ],
};
const ceshi = [
  {
    reg: /^(#|\/)?你好$/,
    fnc: "hello",
  },
  {
    reg: /^(#|\/)?测试$/,
    fnc: "ces",
  },
];
let fncSet = new Set();

for (let i = 0; i < directives.length; i++) {
  const fnc = directives[i].fnc;
  if (fncSet.has(fnc)) {
    console.log(fnc + "出现相同");
  }
  fncSet.add(fnc);
}

/**
 * 加载逻辑
 */
async function load() {
  console.log("开始进行初始化操作和进行加载~");
  const mods_path = path.join(Dirpath, "mods");
  await createDirectoryIfNotExists(path.join(data, "uid"));
  await createDirectoryIfNotExists(mods_path);
  await createDirectoryIfNotExists(player_path);
  await checkFileExists(uid_path);
  const type = [
    "道具列表",
    "功法列表",
    "练气境界",
    "灵根列表",
    "灵魂境界",
    "体魄境界",
    "秘境列表",
    "怪物列表",
    "装备列表",
  ];
  for (let element of type) {
    // let json = (await axios.get(`${url}/${element}.json`)).data;
    // await write_json(7, json, `/${element}.json`);
  }
  await traverseFolder(mods_path);
  console.log("初始化操作和加载成功~");
  console.log(apps$1);
  return {
    apps: apps$1,
    block_status,
  };
}

/**
 * 判断文件夹是否存在
 * @param {*} path 路径
 */
async function createDirectoryIfNotExists(path) {
  try {
    await fs.promises.access(path);
  } catch (error) {
    await fs.promises.mkdir(path, { recursive: true });
  }
}
/**
 * 判断文件是否存在
 * @param filePath 文件路径
 */
async function checkFileExists(filePath) {
  if (!fs.existsSync(filePath)) {
    const name = path.basename(filePath);
    if (name == "uid.json") {
      await write_json(2, []);
    }
  }
}
let block_status = 0;
// 遍历文件夹
let apps$1 = [];
async function traverseFolder(folderPath) {
  const files = await fs.promises.readdir(folderPath);
  for (const file of files) {
    const filePath = path.join(folderPath, file);
    const name = path.basename(folderPath);
    const stats = await fs.promises.stat(filePath);
    if (stats.isDirectory()) {
      await traverseFolder(filePath);
    } else if (file === "index.js") {
      const moduleExports = await import(`file://${filePath}`);
      if (
        moduleExports.load_status ||
        moduleExports.load_status == 1 ||
        moduleExports.load_status == 0
      ) {
        console.log(
          `${name}${moduleExports.load_status === 1 ? "加载成功" : "不加载"}`
        );
      }
      if (moduleExports.load_status == 1) {
        if (moduleExports.item && moduleExports.item.length > 0) {
          for (let index of moduleExports.item) {
            const name = path.basename(index);
            let json = await read_json(0, index);
            await write_json(7, json, `/${name}`);
          }
        }

        if (moduleExports.apps) {
          const app = {};
          let keys = Object.keys(moduleExports.apps);
          keys.forEach((element) => {
            app[element] = moduleExports.apps[element];
          });
          apps$1.push(app);
        }
        if (moduleExports.block) {
          block_status = moduleExports.block;
        }
        // if (moduleExports.directives) {
        //   moduleExports.directives.forEach(element => {
        //     if (element.block && element.block == 1) {
        //       directives = directives.filter(item => item.fnc != element.fnc)
        //     } else if (!element.block) {
        //       const index = directives.findIndex(
        //         item => item.fnc == element.fnc
        //       )
        //       if (index !== -1) {
        //         directives[index] = element
        //       }
        //     }
        //   })
        // }
      }
    }
  }
}

/**
 * @param directory 文件
 * @param data 数据
 * @returns
 */
async function oImages(directory, data = {}) {
  return await oImages2(AppName, Dirpath, directory, data);
}

function App$2() {
    return (React.createElement("html", null,
        React.createElement("head", null,
            React.createElement("link", { rel: "stylesheet", href: "../css/hello.css" })),
        React.createElement("body", null,
            React.createElement("div", { id: "root" },
                React.createElement("h1", null, " Hello, world!")))));
}

const HelpContent = ({ groupData }) => {
    return (React.createElement("div", { className: "cont-box" },
        React.createElement("div", { className: "help-group" }, groupData.group),
        React.createElement("div", { className: "help-table" }, groupData.list.map((item) => (React.createElement("div", { className: "td", key: item.title },
            React.createElement("span", { className: `help-icon ${item.icon}` }),
            React.createElement("strong", { className: "help-title" }, item.title),
            React.createElement("span", { className: "help-desc" }, item.desc)))))));
};

function App$1({ data }) {
    return (React.createElement("html", null,
        React.createElement("head", null,
            React.createElement("meta", { httpEquiv: "X-UA-Compatible", content: "IE=edge" }),
            React.createElement("link", { rel: "stylesheet", type: "text/css", href: "../../public/html/help/help.css" })),
        React.createElement("body", { className: "elem-default default-mode" },
            React.createElement("div", { className: "container", id: "container" },
                data.helpData.map((val) => (React.createElement(HelpContent, { key: val.group, groupData: val }))),
                React.createElement("div", { className: "copyright" },
                    "Xiuxian-Plugin",
                    React.createElement("span", { className: "version" }, ",by \u540D\u5B57(3407318235)"))))));
}

function App({ data }) {
    const { equipment } = data;
    return (React.createElement("html", null,
        React.createElement("link", { rel: "stylesheet", type: "text/css", href: "../../public/html/equipment/equipment.css" }),
        React.createElement("div", { className: "container" },
            React.createElement("h2", null, "\u88C5\u5907\u4FE1\u606F"),
            React.createElement("table", null,
                React.createElement("thead", null,
                    React.createElement("tr", { className: "title-row" },
                        React.createElement("th", null, "\u79CD\u7C7B"),
                        React.createElement("th", null, "\u540D\u79F0"),
                        React.createElement("th", null, "\u653B\u51FB\u52A0\u6210"),
                        React.createElement("th", null, "\u9632\u5FA1\u52A0\u6210"),
                        React.createElement("th", null, "\u751F\u547D\u52A0\u6210"),
                        React.createElement("th", null, "\u8D27\u5E01"))),
                React.createElement("tbody", null,
                    React.createElement("tr", null,
                        React.createElement("td", null, equipment?.武器?.class || "无"),
                        React.createElement("td", null, equipment?.武器?.name || "无"),
                        React.createElement("td", null, equipment?.武器?.攻击加成 || "无"),
                        React.createElement("td", null, equipment?.武器?.防御加成 || "无"),
                        React.createElement("td", null, equipment?.武器?.生命加成 || "无"),
                        React.createElement("td", null,
                            "\u4E0B\u7EA7\u7075\u77F3:",
                            equipment?.武器?.货币?.下级灵石 || 0,
                            ",\u4E2D\u7EA7\u7075\u77F3:",
                            equipment?.武器?.货币?.中级灵石 ||
                                0,
                            ",\u9AD8\u7EA7\u7075\u77F3:",
                            equipment?.武器?.货币?.高级灵石 ||
                                0,
                            ",\u6781\u54C1\u7075\u77F3:",
                            equipment?.武器?.货币?.极品灵石 || 0)),
                    React.createElement("tr", null,
                        React.createElement("td", null, equipment?.胸甲?.class || "无"),
                        React.createElement("td", null, equipment?.胸甲?.name || "无"),
                        React.createElement("td", null, equipment?.胸甲?.攻击加成 || "无"),
                        React.createElement("td", null, equipment?.胸甲?.防御加成 || "无"),
                        React.createElement("td", null, equipment?.胸甲?.生命加成 || "无"),
                        React.createElement("td", null,
                            "\u4E0B\u7EA7\u7075\u77F3:",
                            equipment?.胸甲?.货币?.下级灵石 || 0,
                            ",\u4E2D\u7EA7\u7075\u77F3:",
                            equipment?.胸甲?.货币?.中级灵石 || 0,
                            ",\u9AD8\u7EA7\u7075\u77F3:",
                            equipment?.胸甲?.货币?.高级灵石 ||
                                0,
                            ",\u6781\u54C1\u7075\u77F3:",
                            equipment?.胸甲?.货币?.极品灵石 || 0)),
                    React.createElement("tr", null,
                        React.createElement("td", null, equipment?.腿甲?.class || "无"),
                        React.createElement("td", null, equipment?.腿甲?.name || "无"),
                        React.createElement("td", null, equipment?.腿甲?.攻击加成 || "无"),
                        React.createElement("td", null, equipment?.腿甲?.防御加成 || "无"),
                        React.createElement("td", null, equipment?.腿甲?.生命加成 || "无"),
                        React.createElement("td", null,
                            "\u4E0B\u7EA7\u7075\u77F3:",
                            equipment?.腿甲?.货币?.下级灵石 || 0,
                            ",\u4E2D\u7EA7\u7075\u77F3:",
                            equipment?.腿甲?.货币?.中级灵石 || 0,
                            ",\u9AD8\u7EA7\u7075\u77F3:",
                            equipment?.腿甲?.货币?.高级灵石 ||
                                0,
                            ",\u6781\u54C1\u7075\u77F3:",
                            equipment?.腿甲?.货币?.极品灵石 || 0)),
                    React.createElement("tr", null,
                        React.createElement("td", null, equipment?.法宝?.class || "无"),
                        React.createElement("td", null, equipment?.法宝?.name || "无"),
                        React.createElement("td", null, equipment?.法宝?.攻击加成 || "无"),
                        React.createElement("td", null, equipment?.法宝?.防御加成 || "无"),
                        React.createElement("td", null, equipment?.法宝?.生命加成 || "无"),
                        React.createElement("td", null,
                            "\u4E0B\u7EA7\u7075\u77F3:",
                            equipment?.法宝?.货币?.下级灵石 || 0,
                            ",\u4E2D\u7EA7\u7075\u77F3:",
                            equipment?.法宝?.货币?.中级灵石 || 0,
                            ",\u9AD8\u7EA7\u7075\u77F3:",
                            equipment?.法宝?.货币?.高级灵石 ||
                                0,
                            ",\u6781\u54C1\u7075\u77F3:",
                            equipment?.法宝?.货币?.极品灵石 || 0)))))));
}

class Component {
    pup;
    dir = "";
    constructor(dir) {
        this.pup = new Puppeteer();
        this.dir = dir;
        mkdirSync(this.dir, {
            recursive: true,
        });
    }
    create(element, name) {
        const html = renderToString(element);
        const address = join(this.dir, name);
        writeFileSync(address, `<!DOCTYPE html>${html}`);
        return address;
    }
    hello(name = "help.html") {
        return this.pup.render(this.create(React.createElement(App$2, null), name));
    }
    help(data, name = "help.html") {
        return this.pup.toFile(this.create(React.createElement(App$1, { data: data }), name));
    }
    equipment(data, name = "equipment.html") {
        return this.pup.toFile(this.create(React.createElement(App, { data: data }), name));
    }
}
var component = new Component(join(Dirpath, "public", "cache"));

class start extends plugin {
  constructor() {
    super({
      dsc: "交易模块",
      event: "message",
      rule: [...directives.start],
      priority: 1,
    });
  }
  async rename(e) {
    modifyPlayerInfo(e);
  }
  async Modify_Daoyuan(e) {
    modifyPlayerInfo(e);
  }
  async Change_surname(e) {
    modifyPlayerInfo(e);
  }
  async help(e) {
    // const img = await oImages("/public/html/help/help.html", {
    //   helpData: await read_json(9),
    // });
    // if (img) e.reply(img);
    component
      .help({
        helpData: await read_json(9),
      })
      .then((img) => {
        if (typeof img !== "boolean") e.reply(img);
      });
  }
  async Seeking_Immortal_Destiny(e) {
    if (!(await exist_player(1, e.user_id))) return;
    let { player, bag } = await read_player(1, e.user_id, {
      player: true,
      bag: true,
    });
    if (player.灵根) return e.reply(`你已经寻得仙缘`);
    else if (bag.道具.find((item) => item.name == "测灵石"))
      return e.reply(`你已经寻得仙缘`);
    let random = Math.random();
    if (random < 0.5) {
      e.reply(
        `你在路途上碰到了一个修炼者，他看你骨骼惊奇，他送了你一本入门修炼功法和一块测灵石,并告诉你使用测灵石能测试灵根`
      );
      await add_bag_thing(e.user_id, "入门修炼功法", 1, false);
      await add_bag_thing(e.user_id, "测灵石", 1, false);
    } else {
      e.reply(`未寻得仙缘`);
    }
  }
  async born(e) {
    if (await exist_player(1, e.user_id)) return this.personal_information(e);
    let { new_player, new_equipment, new_bag, fileCount, new_status } =
      await read_default_user();
    new_player.uid = await generateUID();
    new_player.id = fileCount;
    new_player.名号 = `路人甲${fileCount}`;
    new_player.创建存档时间 = getCurrentTime(new Date());
    new_player.生辰八字 = convertToGanZhi(new Date());
    const existingData = await read_json(2);
    existingData.push({
      uid: new_player.uid,
      绑定账号: [e.user_id],
      允许绑定账号: [e.user_id],
    });
    e.reply(`踏入凡世成功`);
    await write_json(2, existingData);
    await write_player(e.user_id, {
      player: new_player,
      equipment: new_equipment,
      bag: new_bag,
      status: new_status,
    });
  }
  async personal_information(e) {
    if (!(await exist_player(1, e.user_id))) return;
    const usr_qq = e.user_id;
    let { player } = await read_player(1, usr_qq, {
      player: true,
    });
    let rank_wuzhe = player.练气境.name;
    let expmax_wuzhe = (await read_json(7, "/练气境界.json")).find(
      (item) => item.name === rank_wuzhe
    )?.灵气;
    let rank_tipo = player.炼体境.name;
    let expmax_tipo = (await read_json(7, "/体魄境界.json")).find(
      (item) => item.name === rank_tipo
    )?.血气;
    let rank_hun = player.灵魂境.name;
    let expmax_hun = (await read_json(7, "/灵魂境界.json")).find(
      (item) => item.name === rank_hun
    )?.灵魂力量;
    const strand_hp = await Strand(player.当前血量, player.血量上限);
    const strand_wuzhe = await Strand(player.灵气, expmax_wuzhe);
    const strand_tipo = await Strand(player.血气, expmax_tipo);
    const strand_hun = await Strand(player.灵魂力量, expmax_hun);
    await write_player(usr_qq, player);
    const img = await oImages("/public/html/player/player.html", {
      player: player,
      rank_wuzhe,
      expmax_wuzhe,
      strand_wuzhe,
      rank_tipo,
      expmax_tipo,
      strand_tipo,
      rank_hun,
      expmax_hun,
      strand_hun,
      strand_hp,
    });
    if (img) e.reply(img);
    return false;
  }
}

class use extends plugin {
  constructor() {
    super({
      dsc: '交易模块',
      event: 'message',
      rule: [...directives.use],
      priority: 1
    });
  }
  async sell(e) {
    if (!(await exist_player(1, e.user_id))) return
    let { player, bag } = await read_player(1, e.user_id, {
      player: true,
      bag: true
    });
    const [thing_name, thing_num] = e.msg
      .replace(/(\/|#)?出售/, '')
      .trim()
      .split('*')
      .map(code => code.trim());
    if (
      !/^\d+(\.\d+)?$/.test(String(thing_num)) ||
      parseInt(thing_num) <= 0 ||
      !Number.isInteger(parseInt(thing_num))
    )
      return e.reply(`请输入大于0且为整数的纯数字`)
    let thing = await find_thing(thing_name);
    if (!thing) return e.reply(`没有这个物品`)
    let bag_thing = bag[thing.type].find(item => item.name == thing_name);
    if (!bag_thing) return e.reply(`你没有这个物品`)
    if (bag_thing.数量 < thing_num)
      return e.reply(`数量不足，你只有${bag_thing.数量}`)
    const type = ['下级灵石', '中级灵石', '高级灵石', '极品灵石'];
    let message = [];
    type.forEach(element => {
      const money = Math.floor(thing.货币[element] * 0.9);
      player.货币[element] += money;
      message.push(`\n${element}:${money}`);
    });
    e.reply(`出售成功,获得${message}`);
    await write_player(e.user_id, { player });
    await add_bag_thing(e.user_id, thing_name, -thing_num, thing);
  }
  async use(e) {
    if (!(await exist_player(1, e.user_id))) return
    let { player, bag } = await read_player(1, e.user_id, {
      player: true,
      bag: true
    });
    const [thing_name, thing_num] = e.msg
      .replace(/(\/|#)?使用/, '')
      .trim()
      .split('*')
      .map(code => code.trim());
    if (
      !/^\d+(\.\d+)?$/.test(String(thing_num)) ||
      parseInt(thing_num) <= 0 ||
      !Number.isInteger(parseInt(thing_num))
    )
      return e.reply(`请输入大于0且为整数的纯数字`)
    let thing = await find_thing(thing_name);
    if (!thing) return e.reply(`没有这个物品`)
    let bag_thing = bag[thing.type].find(item => item.name == thing_name);
    if (!bag_thing) return e.reply(`你没有这个物品`)
    if (bag_thing.数量 < thing_num)
      return e.reply(`数量不足，你只有${bag_thing.数量}`)
    if (thing_name == '测灵石') {
      if (player.灵根) return e.reply(`已经测出灵根`)
      player.灵根 = await get_Spiritual_Root();
      e.reply(
        `测灵石上缓缓显现出你的灵根${player.灵根.name}【${player.灵根.品级}】`
      );
      player.修炼效率 += player.灵根.修炼加成;
    } else if (thing_name == '入门修炼功法') {
      player.境界 = (await read_json(7, '/练气境界.json'))[1];
      player.修炼效率 += 0.01;
      e.reply(`习得入门修炼功法,正式踏入仙途,境界提升`);
    } else if (thing_name == '低级强灵丹') {
      const exp = item_value['低级强灵丹'];
      player.灵气 += parseInt(exp);
    }
    if (thing.type == '功法') {
      thing.熟练度 = 0;
      thing.熟练度等级 = '初学乍练';
      bag[已学习功法].push({
        ...thing,
        数量: 1
      });
    }
    await add_bag_thing(e.user_id, thing_name, -thing_num, thing);
    await write_player(e.user_id, { player, bag });
  }
}

class tupo extends plugin {
  constructor() {
    super({
      dsc: '交易模块',
      event: 'message',
      rule: [...directives.tupo],
      priority: 1
    });
  }
  async tupo(e) {
    if (e.msg.includes('修为')) {
      await get_tupo(e, '练气境界', '练气境');
    } else if (e.msg.includes('体魄') || e.msg.includes('血气')) {
      await get_tupo(e, '体魄境界', '炼体境');
    } else {
      await get_tupo(e, '灵魂境界', '灵魂境');
    }
  }
}

class state extends plugin {
  constructor() {
    super({
      dsc: '交易模块',
      event: 'message',
      rule: [...directives.status],
      priority: 1
    });
  }
  async biguan(e) {
    get_status(e, '闭关');
  }
  async duanlian(e) {
    get_status(e, '锻炼体魄');
  }
  async chuilian(e) {
    get_status(e, '锤炼灵魂');
  }
  async now_status(e) {
    getCurrentFunctionName(e);
  }
  async dagong(e) {
    get_status(e, '打工');
  }
  async lieyao(e) {
    get_status(e, '猎杀妖兽');
  }
  async state_settlement(e) {
    state_settlement(e);
  }
}

class show extends plugin {
  constructor() {
    super({
      dsc: '交易模块',
      event: 'message',
      rule: [...directives.show],
      priority: 1
    });
  }
  async my_bag(e) {
    if (!(await exist_player(1, e.user_id))) return
    let { player, bag } = await read_player(1, e.user_id, {
      player: true,
      bag: true
    });
    let strand_hp = await Strand(player.当前血量, player.血量上限);
    let temp = {
      player: player,
      strand_hp,
      bag
    };
    const img = await oImages('/public/html/bag/bag.html', temp);
    if (img) e.reply(img);
  }
}

class zhandou extends plugin {
  constructor() {
    super({
      dsc: "交易模块",
      event: "message",
      rule: [...directives.zhandou],
      priority: 1,
    });
  }
  async Battlefield(e) {
    if (!(await exist_player(1, e.user_id))) return;
    const [id] = e.msg
      .replace(/(\/|#)?比斗/, "")
      .trim()
      .split("*")
      .map((code) => code.trim());
    if (!(await exist_player(1, id))) return e.reply(`对方无存档`);
    let { player } = await read_player(1, e.user_id, {
      player: true,
    });
    let { player: B_player } = await read_player(1, id, {
      player: true,
    });
    let A_player = await createPlayerObject(player);
    let BB_player = await createPlayerObject(B_player);
    const msg = await playerBattle(A_player, BB_player);
    player.当前血量 = msg.B_damage;
    B_player.当前血量 = msg.A_damage;
    const type = ["灵气", "血气"];
    type.forEach((element) => {
      player[element] += 100;
      B_player[element] += 100;
    });
    e.reply(await oImages("/public/html/msg/msg.html", { temp: msg.msg }));
    await write_player(e.user_id, { player });
    await write_player(id, { player: B_player });
  }
}

class skill extends plugin {
  constructor() {
    super({
      dsc: '交易模块',
      event: 'message',
      rule: [...directives.skill],
      priority: 1
    });
  }
  async configuration(e) {
    if (!(await exist_player(1, e.user_id))) return
    const [thing_name, skill_name] = e.msg
      .replace(/(\/|#)?配置技能栏/, '')
      .trim()
      .split('*')
      .map(code => code.trim());
    if (!thing_name && !skill_name) return e.reply(`缺失参数`)
    let { player, bag } = await read_player(1, e.user_id, {
      player: true,
      bag: true
    });

    const numberPattern = /\d+/;
    const number = thing_name.match(numberPattern);

    if (
      thing_name.includes('技能') &&
      number !== null &&
      (number < 0 || number > 8)
    ) {
      return e.reply(`没有这个技能栏`)
    }
    // if (!player.技能栏[thing_name]) return e.reply(`没有这个技能栏`)
    const bag_skill = bag.已学习功法.find(item => item.name == skill_name);
    if (!bag_skill) return e.reply(`【${player.名号}】你没有学习这门功法`)
    player.技能栏[thing_name] = skill_name;
    e.reply(`【${player.名号}】配置成功`);
    await write_player(e.user_id, { player });
  }
  async check_skill(e) {
    if (!(await exist_player(1, e.user_id))) return
    let { player } = await read_player(1, e.user_id, {
      player: true
    });
    e.reply(`
    技能1:${player.技能栏.技能1 || '无'}
    技能2:${player.技能栏.技能2 || '无'}
    技能3:${player.技能栏.技能3 || '无'}
    技能4:${player.技能栏.技能4 || '无'}
    技能5:${player.技能栏.技能5 || '无'}
    技能6:${player.技能栏.技能6 || '无'}
    技能7:${player.技能栏.技能7 || '无'}
    技能8:${player.技能栏.技能8 || '无'}
   `);
  }
}

class mijing extends plugin {
  constructor() {
    super({
      dsc: "交易模块",
      event: "message",
      rule: [...directives.mysterious_realm],
      priority: 1,
    });
  }
  async check_mijing(e) {
    let [page] = e.msg
      .replace(/(\/|#)?查看秘境/, "")
      .trim()
      .split("*")
      .map((code) => code.trim());
    let pages = parseInt(page);
    if (Number(pages) <= 0) return e.reply(`页数不能小于等于0`);
    if (!pages) pages = 1; // 如果没有输入页数，则默认设为1
    let mijing = await read_json(7, "/秘境列表.json");
    let all_pages = Math.ceil(mijing.length / 4);
    if (all_pages < Number(pages)) return e.reply(`没有这一页`);
    const startIndex = 10 * (Number(pages) - 1);
    const endIndex = startIndex + 10;
    const pageData = mijing.slice(startIndex, endIndex); // 获取当前页的数据
    e.reply(
      await oImages("/public/html/mijing/mijing.html", {
        page: pages,
        all_pages,
        mijing: pageData,
      })
    );
  }
  async go_mijing(e) {
    if (!(await exist_player(1, e.user_id))) return;
    const [thing_name] = e.msg
      .replace(/(\/|#)?前往秘境/, "")
      .trim()
      .split("*")
      .map((code) => code.trim());
    if (!thing_name) return e.reply(`缺失参数`);
    let { player, status } = await read_player(1, e.user_id, {
      player: true,
      status: true,
    });
    if (await redisManager.get_redis_key("mijing" + player.uid))
      return e.reply(`你在秘境中`);
    let mijing = (await read_json(7, "/秘境列表.json")).find(
      (item) => item.name == thing_name
    );
    status.秘境 = new Date().getTime();
    if (!mijing) return e.reply(`没有这个秘境`);
    await redisManager.set_redis_key("mijing" + player.uid, {
      uid: player.uid,
      start_time: new Date().getTime(),
      秘境目标: thing_name,
    });
    await write_player(e.user_id, { status, player });
    e.reply(`【${player.名号}】开始前往【${thing_name}】`);
  }
  async check_stop_mijing(e) {
    if (!(await exist_player(1, e.user_id))) return;
    let { player } = await read_player(1, e.user_id, {
      player: true,
    });
    const [page] = e.msg
      .replace(/(\/|#)?查看已结算秘境/, "")
      .trim()
      .split("*")
      .map((code) => code.trim());
    let numpage = parseInt(page);
    if (!numpage) numpage = 1;
    let data = await redisManager.get_redis_key("stop-mijing" + player.uid);
    if (!data) return e.reply(`无已结算秘境`);
    if (data.length <= 0) return e.reply(`无已结算秘境`);
    let stop = data.sort((a, b) => b.id - a.id);
    let all_pages = Math.ceil(stop.length / 10);
    if (all_pages < Number(numpage)) return e.reply(`没有这一页`);
    const startIndex = 10 * (Number(numpage) - 1);
    const endIndex = startIndex + 10;
    const pageData = stop.slice(startIndex, endIndex); // 获取当前页的数据
    let msg = ["已结算秘境"];
    console.log(pageData);
    pageData.forEach((element) => {
      msg.push(
        `\n秘境编号${element.id},状态:已结束,获得物品${
          element?.thing?.name || "空气"
        }*1`
      );
    });
    e.reply(msg);
  }
}

class 测试 extends plugin {
  constructor() {
    super({
      dsc: "交易模块",
      event: "message",
      rule: [...ceshi],
      priority: 1,
    });
  }
  async hello(e) {
    component.hello().then((img) => {
      if (typeof img !== "boolean") e.reply(img);
    });
  }
}

schedule.scheduleJob("* * * * *", async function () {
  console.log("秘境定时任务开始执行");
  const all_redis = await redisManager.get_all_redis_key("mijing");
  if (all_redis) {
    let 怪物列表 = await read_json(7, "/怪物列表.json");
    for (let redis of all_redis) {
      if (redis.id) continue;
      if (new Date().getTime() - redis.start_time >= mijingCD) {
        let all_boss = 怪物列表.filter((item) =>
          item.秘境.includes(redis.秘境目标)
        );
        let 秘境 = (await read_json(7, "/秘境列表.json")).find(
          (item) => item.name == redis.秘境目标
        );
        let boss = await rouletteWheelSelection(all_boss);
        if (!boss) {
          while (!boss) {
            boss = await rouletteWheelSelection(all_boss);
          }
        }
        let { player, status } = await read_player(1, redis.uid, {
          player: true,
          status: true,
        });
        const A_player = await createPlayerObject(player);
        const B_player = await createPlayerObject(boss);
        const msg = await playerBattle(A_player, B_player);
        player.当前血量 = msg.B_damage;
        let thing = null;
        if (msg.winner == player.名号) {
          let thing_name = (await rouletteWheelSelection(秘境.thing)).name;
          if (!thing_name) {
            while (!thing_name) {
              thing_name = (await rouletteWheelSelection(秘境.thing)).name;
            }
          }
          thing = await find_thing(thing_name);
          await add_bag_thing(player.uid, thing.name, 1, thing);
        }
        let data = await redisManager.get_redis_key("stop-mijing" + player.uid);
        if (!data) {
          await redisManager.set_redis_key("stop-mijing" + player.uid, [
            {
              id: 1,
              msg: msg.msg,
              thing: thing,
            },
          ]);
        } else {
          data.push({
            id: data.length + 1,
            msg: msg.msg,
            thing: thing,
          });
          await redisManager.set_redis_key("stop-mijing" + player.uid, data);
        }
        await redisManager.del_redis_key("mijing" + player.uid);
        status.秘境 = 0;
        await write_player(player.uid, { player, status });
        console.log("秘境结算成功");
      }
    }
  }
});

class equiment extends plugin {
  constructor() {
    super({
      event: "message",
      rule: [...directives.equiment],
      priority: 1,
    });
  }
  async myEquipment(e) {
    if (!(await exist_player(1, e.user_id))) return;
    let { equipment } = await read_player(1, e.user_id, {
      equipment: true,
    });
    component
      .equipment({
        equipment,
      })
      .then((img) => {
        if (typeof img !== "boolean") e.reply(img);
      });
  }
  async remove_gear(e) {
    if (!(await exist_player(1, e.user_id))) return;
    const [thing_name] = e.msg
      .replace(/(\/|#)?卸下装备/, "")
      .trim()
      .split("*")
      .map((code) => code.trim());
    let { equipment, player } = await read_player(1, e.user_id, {
      equipment: true,
      player: true,
    });
    const thing = await find_thing(thing_name);
    if (!thing) return e.reply(`没有查找到[${thing_name}]这件装备`);
    if (!equipment[thing.class] || equipment[thing.class].name != thing_name)
      return e.reply(
        `[${player.名号}]你[${thing.class}]装备位上没有${thing_name}这件装备`
      );
    player = updatePlayerAttributes(player, thing, false);
    equipment[thing.class] = null;
    await add_bag_thing(e.user_id, thing.name, 1, thing);
    await write_player(e.user_id, { equipment, player });
    return e.reply(`[${player.名号}]你的${thing_name}卸下成功`);
  }
  async all_equipment(e) {
    if (!(await exist_player(1, e.user_id))) {
      return;
    }
    let { equipment, bag, player } = await read_player(1, e.user_id, {
      equipment: true,
      bag: true,
      player: true,
    });
    async function equipAndUpdate(equipment_name) {
      const type = find_equipment(
        bag,
        equipment[equipment_name],
        equipment_name
      );
      if (type) {
        const eq = await find_thing(type);
        if (equipment[equipment_name]) {
          player = updatePlayerAttributes(
            player,
            equipment[equipment_name],
            false
          );
          await add_bag_thing(
            e.user_id,
            equipment[equipment_name].name,
            1,
            equipment[equipment_name]
          );
        }
        await add_bag_thing(e.user_id, eq.name, -1, eq);
        equipment[equipment_name] = eq;
        player = updatePlayerAttributes(
          player,
          equipment[equipment_name],
          true
        );
        return { equiment: equipment[equipment_name], player };
      }
    }
    const types = ["武器", "胸甲", "腿甲", "法宝"];
    for (let i of types) {
      await equipAndUpdate(i);
    }
    await write_player(e.user_id, { equipment, player });
    return e.reply(`[${player.名号}]一键装备成功`);
  }
  async equipment(e) {
    if (!(await exist_player(1, e.user_id))) return;
    let { equipment, bag, player } = await read_player(1, e.user_id, {
      equipment: true,
      bag: true,
      player: true,
    });
    const [thing_name] = e.msg
      .replace(/(\/|#)?装备/, "")
      .trim()
      .split("*")
      .map((code) => code.trim());
    if (!thing_name) return e.reply(`缺失参数`);
    const bag_thing = bag.装备.find((item) => item.name == thing_name);
    if (!bag_thing)
      return e.reply(`在你的背包中没有找到[${thing_name}]这个东西`);
    const thing = await find_thing(thing_name);
    if (!thing) return e.reply(`没有找到[${thing_name}]这个东西`);
    if (equipment[thing.class]) {
      player = updatePlayerAttributes(player, equipment[thing.class], false);
      await add_bag_thing(
        e.user_id,
        equipment[thing.class].name,
        +1,
        equipment[thing.class]
      );
      equipment[thing.class] = thing;
    } else {
      player = updatePlayerAttributes(player, equipment, true);
    }
    e.reply(`装备成功`);
    await add_bag_thing(e.user_id, thing_name, -1, thing);
    await write_player(e.user_id, { equipment, player });
  }
  async practise_(e) {
    if (!(await exist_player(1, e.user_id))) return;
    let { equipment, status, player } = await read_player(1, e.user_id, {
      equipment: true,
      status: true,
      player: true,
    });
    if (!equipment.武器) {
      return e.reply(`你没有装备任何的武器`);
    }
    const now_status = await getNonZeroValues(status);
    if (now_status) return e.reply(`你在${now_status}`);

    for (const key in weaponTypes) {
      if (equipment.武器.类型 !== weaponTypes[key] && e.msg.includes(key)) {
        return e.reply(
          `[${equipment.武器.name}]武器类型不是[${weaponTypes[key]}]`
        );
      }
    }
    status.练习武器 = new Date().getTime();
    e.reply(
      `开始练习${equipment.武器.类型}[${await getCurrentTime(new Date())}]`
    );
    await redisManager.set_redis_key(
      "practise-wuqi" + player.uid,
      equipment.武器.类型
    );
    await write_player(e.user_id, { status });
  }
  async tupo_(e) {
    if (!(await exist_player(1, e.user_id))) return;
    let { player } = await read_player(1, e.user_id, {
      player: true,
    });
    let type = null;
    for (const key in weaponTypes) {
      if (e.msg.includes(key)) {
        type = key;
      }
    }
    const keys = Object.keys(Weapon_proficiency);
    if (
      !player.武器熟练度[type + "等级"] &&
      player.武器熟练度[type + "熟练度"] >= Weapon_proficiency.初窥门道
    ) {
      player.武器熟练度[type + "熟练度"] -= Weapon_proficiency.初窥门道;
      player.武器熟练度[type + "等级"] = keys[0];
      e.reply(`[${type}]的熟练度提升成功,目前等级为[${keys[0]}]`);
    } else if (
      !player.武器熟练度[type + "等级"] &&
      player.武器熟练度[type + "熟练度"] <= Weapon_proficiency.初窥门道
    ) {
      return e.reply(`连[初窥门道]的熟练度门槛都没达到，也想突破熟练度?`);
    } else {
      let location =
        keys.findIndex((item) => item == player.武器熟练度[type + "等级"]) + 1;
      if (!keys[location])
        return e.reply(
          `你的[${type}]熟练度以达到最高[${keys[location - 1]}]之境`
        );
      else if (
        player.武器熟练度[type + "熟练度"] >= Weapon_proficiency[keys[location]]
      ) {
        player.武器熟练度[type + "熟练度"] -=
          Weapon_proficiency[keys[location]];
        player.武器熟练度[type + "等级"] = keys[location];
        e.reply(`[${type}]的熟练度提升成功,目前等级为[${keys[location]}]`);
      } else {
        return e.reply(
          `你目前的[${type}]熟练度难以达到最高[${keys[location]}]之境`
        );
      }
    }
    await write_player(e.user_id, { player });
  }
  async check_wuqi(e) {
    if (!(await exist_player(1, e.user_id))) return;
    let { player } = await read_player(1, e.user_id, {
      player: true,
    });
    const keys = Object.keys(Weapon_proficiency);
    async function getWeaponStrand(proficiency, level, proficiencyArray, keys) {
      let index = keys.findIndex((item) => item == level);
      if (index !== -1) {
        return {
          index,
          strand: await Strand(proficiency, proficiencyArray[keys[index + 1]]),
        };
      } else {
        return {
          index: 0,
          strand: await Strand(proficiency, proficiencyArray[keys[0]]),
        };
      }
    }
    const { strand: strand_剑, index: index_剑 } = await getWeaponStrand(
      player.武器熟练度.剑熟练度,
      player.武器熟练度.剑等级,
      Weapon_proficiency,
      keys
    );

    const { strand: strand_枪, index: index_枪 } = await getWeaponStrand(
      player.武器熟练度.枪熟练度,
      player.武器熟练度.枪等级,
      Weapon_proficiency,
      keys
    );

    const { strand: strand_弓, index: index_弓 } = await getWeaponStrand(
      player.武器熟练度.弓熟练度,
      player.武器熟练度.弓等级,
      Weapon_proficiency,
      keys
    );
    const { strand: strand_棍, index: index_棍 } = await getWeaponStrand(
      player.武器熟练度.棍熟练度,
      player.武器熟练度.棍等级,
      Weapon_proficiency,
      keys
    );
    e.reply(
      await oImages("/public/html/equipment/equipment1.html", {
        player,
        strand_弓,
        strand_棍,
        strand_枪,
        strand_剑,
        Weapon_proficiency,
        index_棍,
        index_弓,
        index_枪,
        index_剑,
        keys,
      })
    );
  }
}

var apps = /*#__PURE__*/Object.freeze({
  __proto__: null,
  equiment: equiment,
  mijing: mijing,
  show: show,
  skill: skill,
  start: start,
  state: state,
  tupo: tupo,
  use: use,
  zhandou: zhandou,
  测试: 测试
});

const x = await load();
console.info(`轻量修仙启动 ~`);
let newApps;
if (x.block_status == 0) {
  newApps = Object.assign({}, apps);
} else {
  newApps = {};
}
for (const app of x.apps) {
  const keys = Object.keys(app);
  keys.forEach((key) => {
    newApps[key] = app[key];
  });
}

export { apps };
